/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package emprestimo;

import DAO.DAOGenerico;
import DAO.DAOJSON;
import empregado.Empregado;
import exceptions.ValidacaoEmprestimoException;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import utils.GetAge;

/**
 *
 * @author arruda
 */
public class EmprestimoService {
    private DAOGenerico daoEmprestimo;
    
    public EmprestimoService() {
        daoEmprestimo = new DAOJSON();
    }
    
    public ArrayList<Emprestimo> consultarEmprestimos(Empregado empregado){
        Emprestimo emprestimoConsulta = new Emprestimo(empregado);
        ArrayList<Emprestimo> emprestimos = new ArrayList<Emprestimo>();
        try {
            emprestimos= (ArrayList<Emprestimo>) daoEmprestimo.consultar(emprestimoConsulta);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        
        return emprestimos;
    }
    /**
     * Retorna qual o limite de emprestimo para o empregado atual
     * @param   empregado que deseja o empréstimo consignado
     * @return  salário x percentagem permitida.
     */
    private  double obterLimiteEmprestimo(Empregado emp) throws ValidacaoEmprestimoException {
        //validar as datas de aniversario!!!!!
        int anos = GetAge.getAge(emp.getDtnascimento());
        
        double percentagem= 0.0;
        
        if(emp.getSexo().equals("MASCULINO")){ //homens
            
            if(anos <= 35){ //mudar? //se for entre 21-35?
                if (emp.getSalario() <= 5000) percentagem = 0.7;
                else percentagem = 0.75;
            }
            else if(anos <= 45) {             //se for entre 36-45
                if(emp.getSalario() <= 6000) percentagem=0.55;
                else percentagem=0.6;       
            }
            else if (anos <= 65) percentagem=0.3; //se for entre 46-65
        }
        else{ //mulheres
            if (anos <= 30) percentagem=0.7; //entre 21-30
            else if (anos <= 44) percentagem=0.5; //entre 31-44
            else if (anos <= 61) percentagem=0.35; //entre 45-61
        }
        return emp.getSalario() * percentagem;
    }
    
    
    /**
     * Calcula  o Juros do empréstimo segundo a seguinte fórmula:
     * De 1 a 3 prestações: 5% ao mês. 
     * De 4 a 10 prestações: 6.5% ao mês 
     * De 11 a 15 prestações: 8% ao mês
     * De 16 a 24 prestações: 10% ao mês 
     * 
     * @param numPrest  número de prestações desejadas para o empréstimo
     */
    private  Double calcularJuros(int numPrest){
        if(numPrest <= 3){
            return 0.05;
        }
        else if(numPrest < 10){
            return 0.065;
        }
        else if(numPrest <= 15){
            return  0.08;
        }
        else if(numPrest <= 24){
           return  0.1;
        }
        return null;
    }
    
    /**
     * Calcula e altera as o valor de cada prestacao de acordo com o juros, com o valor do emprestimo e o número de prestações
     * Valor Prestação = Valor Emprestimo * CF
     * CF = juros / ( 1- ( 1/( 1 + juros) ^ prestacoes ) )
     * @param prestacoes 
     * @param emprestimo
    */
    private  Double calcularPrestacoes(Double juros, int numeroPrestacoes, double emprestimo){
        double denominador = 1 - (1 / Math.pow(1 + juros, numeroPrestacoes));
        double cf = juros / denominador;
        
        return emprestimo * cf;
    }
    /**
     * Chama métodos para validação e calculos do empréstimo. Cria o objeto emprestimo com as informações calculadas
     * @param empregado    objeto Empregado contendo as informações sobre o empregado que possui o CPF informado
     * @param valorEmprestimo    Double contendo o valor informado ao calcular o empréstimo
     * @param numeroPrestacoes    int contendo o número de parcelas informado ao calcular o empréstimo
    */
    public Emprestimo prepararEmprestimo(Empregado empregado, double valorEmprestimo, int numeroPrestacoes) throws ValidacaoEmprestimoException{        
   
        this.validarEmprestimo(empregado, valorEmprestimo, numeroPrestacoes);
        
        double juros = calcularJuros(numeroPrestacoes);
        double prestacoes =  calcularPrestacoes(juros,numeroPrestacoes,valorEmprestimo);
        Emprestimo emprestimo = new Emprestimo(empregado);
        emprestimo.setJuros(juros);
        emprestimo.setNumPrestacoes(numeroPrestacoes);
        emprestimo.setValorDesejado(valorEmprestimo);
        emprestimo.setPrestacao(prestacoes);
        
        return emprestimo;
    }
    /**
     * Guarda empréstimo calculado em prepararEmprestimo na base JSON 
     * @param empregado    objeto Empregado contendo as informações sobre o empregado que possui o CPF informado
     * @param emprestimo    objeto Emprestimo criado com as informações geradas segundo o empregado e os valores de entrada do empréstimo
    */
    public void fazerEmprestimo(Empregado empregado,Emprestimo emprestimo) throws Exception {
        emprestimo.setId(GregorianCalendar.getInstance().getTimeInMillis());
        daoEmprestimo.salvar(emprestimo);
        
    }
    
    /**
     * Verifica se todas as condições para que o emprestimo seja feito foram satisfeitas.
     * @param empregado     objeto Empregado contendo as informações sobre o Empregado que fez a solicitação pelo empréstimo
     * @param emprestimo    valor solicitado como empréstimo
     * @param prestacoes    número de prestações desejadas para pagamento
     * @return  false caso alguma regra não seja atendida. True caso contrário
    */
    private void validarEmprestimo(Empregado empregado, Double emprestimo, int numeroPrestacoes) throws ValidacaoEmprestimoException{
        if(empregado == null) throw new ValidacaoEmprestimoException("Empregado inválido");        
        if(empregado.getDtdesligamento() != null) throw new ValidacaoEmprestimoException("Empregado inválido");
        if(empregado.getSexo().equals("MASCULINO")){
            if(GetAge.getAge(empregado.getDtnascimento())<21)throw new ValidacaoEmprestimoException("Empregado muito novo");
            if(GetAge.getAge(empregado.getDtnascimento())>65)throw new ValidacaoEmprestimoException("Empregado muito velho");        
        }else{
            if(GetAge.getAge(empregado.getDtnascimento())<21)throw new ValidacaoEmprestimoException("Empregado muito novo");
            if(GetAge.getAge(empregado.getDtnascimento())>61)throw new ValidacaoEmprestimoException("Empregado muito velho");    
        }
        if(numeroPrestacoes < 1 || numeroPrestacoes > 24) throw new ValidacaoEmprestimoException("numeroPrestacoes invalido");
        Double limiteEmprestimo = this.obterLimiteEmprestimo(empregado);
        if(emprestimo > limiteEmprestimo) throw new ValidacaoEmprestimoException("valorEmprestimo muito alto");
    }
    
    
}
